Repository navigation
feat(growth): turn suggestion backend - #106432
Conversation
🤖 CI report
|
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.64 MiB · 23 files | no change | █████████░ 88.9% of 1.84 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
3.72 MiB · 663 files | no change | █████████░ 92.3% of 4.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.62 MiB · 2,415 files | no change | █████████░ 91.4% of 8.34 MiB |
🟡 dashboard scenesrc/scenes/dashboard/Dashboard.tsx |
13.90 MiB · 4,917 files | no change | ██████████ 103.2% of 13.48 MiB |
today home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx |
7.64 MiB · 2,427 files | no change | █████████░ 89.0% of 8.58 MiB |
🟡 events scenesrc/scenes/activity/explore/EventsScene.tsx |
13.63 MiB · 4,789 files | no change | ██████████ 107.9% of 12.64 MiB |
replay detail scenesrc/scenes/session-recordings/detail/SessionRecordingDetail.tsx |
12.13 MiB · 4,142 files | no change | ████████░░ 77.2% of 15.72 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/index.tsx |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 839 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 99.7 KiB | src/lib/api.ts |
| 90.6 KiB | src/products.tsx |
| 68.7 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 40.7 KiB | src/lib/utils/eventUsageLogic.ts |
| 38.7 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
| 29.0 KiB | ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 112.3 KiB | ../packages/quill/packages/quill/dist/index.js |
| 99.7 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 90.6 KiB | src/products.tsx |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 315.5 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.8 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 112.3 KiB | ../packages/quill/packages/quill/dist/index.js |
| 99.7 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
| Size | File |
|---|---|
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 112.3 KiB | ../packages/quill/packages/quill/dist/index.js |
| 99.7 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 90.6 KiB | src/products.tsx |
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
| Size | File |
|---|---|
| 315.5 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.8 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 112.3 KiB | ../packages/quill/packages/quill/dist/index.js |
| 99.7 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
| Size | File |
|---|---|
| 315.5 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 306.2 KiB | ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.3 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.8 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 112.3 KiB | ../packages/quill/packages/quill/dist/index.js |
| 99.7 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.21 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.21 MiB · 19 files | no change | ████░░░░░░ 38.7% of 5.72 MiB |
| Deferred (lazy) | 2.12 MiB · 44 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.2 KiB | no change | █░░░░░░░░░ 6.0% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 850.6 KiB | dist/toolbar/toolbar-app-5BH4NJL4.css |
| 657.4 KiB | dist/toolbar/chunk-chunk-R75Z5TYV.js |
| 259.4 KiB | dist/toolbar/chunk-chunk-6EL3FW4B.js |
| 138.2 KiB | dist/toolbar/chunk-chunk-2GNJAOKU.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 75.2 KiB | dist/toolbar/toolbar-app-2PA223GW.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-46UEXYQR.js |
| 21.0 KiB | dist/toolbar/chunk-chunk-Q5QJDMUL.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +7.7 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 998.62 MiB · 🔺 +7.7 KiB (+0.0%)
ℹ️ MCP UI apps size — 32 app(s), 17182.9 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 597.9 KB | 202.7 KB |
| action | 454.2 KB | 202.7 KB |
| action-list | 564.3 KB | 202.7 KB |
| cohort | 453.2 KB | 202.7 KB |
| cohort-list | 563.2 KB | 202.7 KB |
| email-template | 453.0 KB | 202.7 KB |
| error-details | 469.7 KB | 202.7 KB |
| error-issue | 454.5 KB | 202.7 KB |
| error-issue-list | 564.9 KB | 202.7 KB |
| experiment | 561.4 KB | 202.7 KB |
| experiment-list | 565.0 KB | 202.7 KB |
| experiment-results | 566.4 KB | 202.7 KB |
| feature-flag | 566.8 KB | 202.7 KB |
| feature-flag-list | 570.6 KB | 202.7 KB |
| feature-flag-testing | 457.3 KB | 202.7 KB |
| inline-scan | 453.6 KB | 202.7 KB |
| insight-actors | 562.4 KB | 202.7 KB |
| llm-costs | 559.4 KB | 202.7 KB |
| session-recording | 455.4 KB | 202.7 KB |
| survey | 454.8 KB | 202.7 KB |
| survey-global-stats | 561.9 KB | 202.7 KB |
| survey-list | 565.0 KB | 202.7 KB |
| survey-stats | 561.9 KB | 202.7 KB |
| trace-span | 453.5 KB | 202.7 KB |
| trace-span-list | 564.2 KB | 202.7 KB |
| vision-observation-list | 563.3 KB | 202.7 KB |
| workflow | 453.5 KB | 202.7 KB |
| workflow-list | 563.6 KB | 202.7 KB |
| loops-review | 457.9 KB | 202.7 KB |
| query-results | 774.3 KB | 202.7 KB |
| render-ui | 857.7 KB | 202.7 KB |
| visual-review-snapshots | 458.0 KB | 202.7 KB |
✅ ClickHouse migration SQL — none
No ClickHouse migrations in the latest push.
✅ Hogbox preview — ready, open the preview
▶ Open the preview
| 🔑 Login | test@posthog.com / 12345678 (demo data) |
| 🧩 Running | this PR's backend and frontend, on the PostHog :master base |
| 🔗 Link | stable across rebuilds: a re-push swaps the box underneath, the URL stays |
| 🔒 Access | tailnet only (PostHog VPN) |
| 🛠️ Admin | inspect & debug state in hogland |
| 💤 Idle | sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen |
commit 12f5841 · box box-c48b6aa63329 · ready in 735s (push → usable) · build log · rebuilds on every push, torn down on close
|
[High risk] Adds a new background job queue and task processing system. The PR should not merge until the judge can distinguish eligible insights without exposing sensitive names. Reviews (3) · Last reviewed commit: "fix(growth): mask insight names and keep..." |
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: PostHog/posthog/.coderabbit.yaml Review profile: QUIET Plan: Enterprise Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (22)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 12 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe change adds PostHog AI turn suggestions. It extracts and redacts conversation transcripts, judges turns, selects and drafts offers, and records and publishes suggestions. Completed task runs can trigger delayed generation through a new Celery queue. Task-scoped API endpoints return suggestion state and record resolutions. MCP tool definitions, generated API types, and tests are also added. Priority: ⬇️ Low Merge Risk: 🔵 Low · up to This adds turn suggestion processing for PostHog AI behind a flag that is off by default. Earlier concerns about a crash on large turns and a type-check failure appear to be addressed, but neither fix has been confirmed at the current head. Before enabling the feature, confirm that CI passes, that the posthog_ai worker runs in each region, and that the TypeSafe fallback does not send customer text. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to Access checks and consent checks are present, but an interrupted background operation can leave a suggestion recorded without displaying it. The new endpoints and worker path also depend on access enforcement and regional deployment conditions that are not fully verified here. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
products/posthog_ai/backend/turn_suggestions/judgment.py-205-214 (1)
205-214: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winCap the insight and issue options. Otherwise a large turn crashes the task.
_issue_optionsand_insight_optionsnumber every ref in the transcript._error_issuesintranscript.pycollects every row from everyquery-error-tracking-issues-listresult in the turn. For example, a turn with a few 100-row list calls can yield more than 254 distinct issues. With the addednoneoption,ChoiceQuestion.__post_init__then raisesValueErrorbecause the count exceedsMAX_CHOICE_OPTIONS.
build_judge_questionsruns inside thetryinjudge_turn, but theexceptclauses catch only the TypeSafe errors andOSError. TheValueErrortherefore propagates out ofgenerate_turn_suggestion_task.claim_turnhas already run at that point, so the turn is consumed without a recorded outcome or analytics event.Cap the refs in one place.
build_judge_stateandread_judgmentuse the same helpers, so the state, the questions and the answer lookup stay in sync.Proposed fix
+# One option stays free for `_NO_MATCH`; see MAX_CHOICE_OPTIONS in posthog.egress.typesafe. +_MAX_REF_OPTIONS = 50 + def _numbered[T](prefix: str, refs: Sequence[T]) -> dict[str, T]: - return {f"{prefix}_{index}": ref for index, ref in enumerate(refs, start=1)} + return {f"{prefix}_{index}": ref for index, ref in enumerate(refs[:_MAX_REF_OPTIONS], start=1)}
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 3f5b4fd9-99ea-4812-8e43-0c9d4db24213
⛔ Files ignored due to path filters (3)
products/posthog_ai/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.zod.tsis excluded by!**/generated/**
📒 Files selected for processing (22)
bin/celery-queues.envposthog/celery_queues.pyposthog/egress/typesafe/README.mdproducts/posthog_ai/backend/api/__init__.pyproducts/posthog_ai/backend/api/turn_suggestions.pyproducts/posthog_ai/backend/receivers.pyproducts/posthog_ai/backend/routes.pyproducts/posthog_ai/backend/tasks.pyproducts/posthog_ai/backend/tests/test_turn_suggestions.pyproducts/posthog_ai/backend/tests/test_turn_suggestions_api.pyproducts/posthog_ai/backend/turn_suggestions/__init__.pyproducts/posthog_ai/backend/turn_suggestions/classifier.pyproducts/posthog_ai/backend/turn_suggestions/dispatch.pyproducts/posthog_ai/backend/turn_suggestions/drafter.pyproducts/posthog_ai/backend/turn_suggestions/judgment.pyproducts/posthog_ai/backend/turn_suggestions/offer_ledger.pyproducts/posthog_ai/backend/turn_suggestions/service.pyproducts/posthog_ai/backend/turn_suggestions/transcript.pyproducts/posthog_ai/backend/turn_suggestions/verdict.pyproducts/posthog_ai/mcp/tools.yamlservices/mcp/src/api/generated.tstach.toml
Included review availability: Your plan provides up to 12 included reviews per hour; 5 remain after this review.
b01e9e0 to
24076a6
Compare
24076a6 to
bae2470
Compare
|
@coderabbitai review-body comment:
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
git show --stat --oneline bae2470ae09
git show --format=fuller --no-ext-diff bae2470ae09 -- products/posthog_ai/backend/turn_suggestions/judgment.py products/posthog_ai/backend/turn_suggestions/transcript.py
ast-grep outline products/posthog_ai/backend/turn_suggestions/judgment.py --match 'build_judge_state|build_judge_questions|read_judgment'
rg -n -C 4 'saved_insights|error_issues|MAX_.*OPTIONS|insight_options|issue_options' products/posthog_ai/backend/turn_suggestions/judgment.py products/posthog_ai/backend/turn_suggestions/transcript.pyLength of output: 23649
You are interacting with an AI system. |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
products/posthog_ai/backend/turn_suggestions/transcript.py-254-262 (1)
254-262: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAssemble streamed
user_message_chunkframes before starting a turn.ACP permits one user message to arrive as multiple
user_message_chunkupdates with the samemessageId. The backend currently callsstart_turnfor every chunk, and exact-text deduplication cannot match a full_posthog/user_messageagainst an individual chunk. The frontend parser also emits one user item per chunk without assemblingmessageIdgroups.Accumulate chunks by
messageIdbefore callingstart_turn, then apply the existing deduplication to the assembled message.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 4aef9b4b-d343-4e6f-b973-1d6b14722fc4
⛔ Files ignored due to path filters (3)
products/posthog_ai/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.zod.tsis excluded by!**/generated/**
📒 Files selected for processing (22)
bin/celery-queues.envposthog/celery_queues.pyposthog/egress/typesafe/README.mdproducts/posthog_ai/backend/api/__init__.pyproducts/posthog_ai/backend/api/turn_suggestions.pyproducts/posthog_ai/backend/receivers.pyproducts/posthog_ai/backend/routes.pyproducts/posthog_ai/backend/tasks.pyproducts/posthog_ai/backend/tests/test_turn_suggestions.pyproducts/posthog_ai/backend/tests/test_turn_suggestions_api.pyproducts/posthog_ai/backend/turn_suggestions/__init__.pyproducts/posthog_ai/backend/turn_suggestions/classifier.pyproducts/posthog_ai/backend/turn_suggestions/dispatch.pyproducts/posthog_ai/backend/turn_suggestions/drafter.pyproducts/posthog_ai/backend/turn_suggestions/judgment.pyproducts/posthog_ai/backend/turn_suggestions/offer_ledger.pyproducts/posthog_ai/backend/turn_suggestions/service.pyproducts/posthog_ai/backend/turn_suggestions/transcript.pyproducts/posthog_ai/backend/turn_suggestions/verdict.pyproducts/posthog_ai/mcp/tools.yamlservices/mcp/src/api/generated.tstach.toml
💤 Files with no reviewable changes (1)
- products/posthog_ai/backend/turn_suggestions/init.py
Included review availability: Your plan provides up to 12 included reviews per hour; 4 remain after this review.
4bfafe9 to
662d586
Compare
662d586 to
db6d16b
Compare
db6d16b to
742e8b8
Compare
|
@coderabbitai review-body comment:
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 49f1298d-483b-4aa2-b1b7-9e9c72370935
⛔ Files ignored due to path filters (3)
products/posthog_ai/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.tsis excluded by!**/generated/**products/posthog_ai/frontend/generated/api.zod.tsis excluded by!**/generated/**
📒 Files selected for processing (22)
bin/celery-queues.envposthog/celery_queues.pyposthog/egress/typesafe/README.mdproducts/posthog_ai/backend/api/__init__.pyproducts/posthog_ai/backend/api/turn_suggestions.pyproducts/posthog_ai/backend/receivers.pyproducts/posthog_ai/backend/routes.pyproducts/posthog_ai/backend/tasks.pyproducts/posthog_ai/backend/tests/test_turn_suggestions.pyproducts/posthog_ai/backend/tests/test_turn_suggestions_api.pyproducts/posthog_ai/backend/turn_suggestions/__init__.pyproducts/posthog_ai/backend/turn_suggestions/classifier.pyproducts/posthog_ai/backend/turn_suggestions/dispatch.pyproducts/posthog_ai/backend/turn_suggestions/drafter.pyproducts/posthog_ai/backend/turn_suggestions/judgment.pyproducts/posthog_ai/backend/turn_suggestions/offer_ledger.pyproducts/posthog_ai/backend/turn_suggestions/service.pyproducts/posthog_ai/backend/turn_suggestions/transcript.pyproducts/posthog_ai/backend/turn_suggestions/verdict.pyproducts/posthog_ai/mcp/tools.yamlservices/mcp/src/api/generated.tstach.toml
💤 Files with no reviewable changes (1)
- products/posthog_ai/backend/turn_suggestions/init.py
Included review availability: Your plan provides up to 12 included reviews per hour; 6 remain after this review.
f965565 to
69230ad
Compare
69230ad to
f676e62
Compare
Classify each completed PostHog AI turn and publish an end-of-turn suggestion frame. The task runs on a new posthog_ai Celery queue, a short Redis lock drops duplicate turn reports before they are queued, and the offer ledger in the task state is the only stored outcome of a card: a reload reads it from the new state endpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…blishing - read insight and issue refs from the MCP app-data envelope, and resolve tool identity from the adapter's _meta.posthog stamp - note a follow-up that is still running instead of claiming its turn - skip conversations past the resume chain depth, where turn indexes slide - count a card only when it reached the run log - cap the insight and issue options Jev sees - release the enqueue dedup key when queueing fails, and keep it only for the settle wait - send the Luna draft cap as max_completion_tokens Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g's cost The Luna drafter now uses build_openai_client, so it reaches the Go ai-gateway where AI_GATEWAY_URL is set and bills the wallet of the team that owns that key. The Python fallback moves from the posthog_ai route, which bills the customer's AI credits, to the unbilled growth route. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The judge now asks posthog/hogference/jevk5-fp8-0.2 through the ai-gateway where it is configured, and jev-1.13.0 through TypeSafe elsewhere. Ref options cap at 15, so a choice fits the gateway model's 16 options. The classified event records the model the configured server was asked for. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Master now blocks TypeSafe on PostHog Cloud and its README says a Cloud feature must not pass a TypeSafeFallback. The judge state carries the user's question, so the judge drops the jev-1.13.0 TypeSafe fallback and asks only the PostHog-hosted Jev build on the ai-gateway. Team attribution uses the new team_id argument of build_system_one_client instead of setting the distinct id and team_id property by hand. A TypeSafe key on its own no longer configures the judge, and the failure test checks that no request leaves in that case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ion cap A failed enqueue now releases only its own dedup reservation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- skip a latest turn that has no turn_complete frame yet, so a follow-up still streaming is noted instead of judged and claimed - expire the celery job shortly after the settle wait, so a stalled posthog_ai worker drains no backlog of late cards - count and log every job outcome, and warn when the judge is not configured - mark the insight or issue the answer names, so masked labels that read the same stay distinguishable for jev Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f676e62 to
12f5841
Compare
|
Stacked PR 106435 failed testing in the merge queue. Please investigate the failure and re-submit the stack. |
|
This pull request was merged into |
Problem
Note
This layer needs a worker consuming the new
posthog_aiCelery queue. https://github.com/PostHog/charts/pull/16307 adds it and merged on 2026-09-25. Confirm the worker runs in each region before this layer merges.Changes
posthog/hogference/jevk5-fp8-0.2, through the client from feat(llm): add a system one client that prefers the ai-gateway #106735.Task.stateis the only stored outcome of a card. The newGET turn_suggestions/state/endpoint serves it to a reloaded thread.POST turn_suggestions/resolve/records a dismiss or an accept. It tells other open tabs through a frame on the offer's run and on the task's latest run.posthog-ai-turn-suggestionsflag, AI data processing approval, a conversation started in the web app, and a configured ai-gateway (AI_GATEWAY_URLwithAI_GATEWAY_API_KEY).posthog_aiCelery queue, two seconds after the turn, so the last frames of the answer have landed. A job that has not started 32 seconds after the report expires, so a stalled worker drains no late cards._posthog/turn_completeframe has landed. A follow-up still streaming is noted, not judged, and its own completion classifies it.posthog_ai_turn_suggestion_outcomes_total{status, reason}and logs one line. A missing judge configuration logs a warning.SET NXheld for the two-second settle wait drops the duplicates before they reach the queue.flowchart LR A[Turn completes] --> D[Redis dedup] D --> E[posthog_ai queue] E --> L[Offer ledger gates] L --> G{{Jev judges the masked turn}} G -->|scout or notebook| R{{Luna drafts the text}} G -->|alert, subscription, error alert| H[Suggestion frame] R --> H classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class A phYellow; class G,R phBlue; class D,E,L,H phGray;How did you test this code?
test_turn_suggestions.pycovers the transcript fold, the masked Jev request, the offer policy, the ledger rules and races, and the gates.session/promptframes merge every earlier answer into the last turn.test_turn_suggestions_api.pycovers the state and resolve endpoints.Release status
Automatic notifications
Docs update
None: the feature is behind a flag that is off by default.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Fable 5.1 wrote the original #101991. Claude Opus 5.5 switched the judge to Jev, split the stack and fixed the review findings.
growthroute, never the customer's AI credits.TYPESAFE_API_KEY, so this stack does not use the secret from https://github.com/PostHog/charts/pull/16183.build_system_one_client(team_id=...), to match master's System One rules.🤖 Generated with Claude Code